package com.shopcart.pay.wx;

import java.math.BigDecimal;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.UUID;

import com.shopcart.pay.PayPropertySupport;
import com.shopcart.pay.wx.client.TenpayHttpClient;
import com.shopcart.pay.wx.util.ConstantUtil;
import com.shopcart.pay.wx.util.MD5Util;
import com.shopcart.pay.wx.util.WXUtil;
import com.shopcart.pay.wx.util.XMLUtil;

/**
 * 微信预支付订单号
 * @author sun
 *
 */
public class WxPrepay {

	private static String unifiedorder = "https://api.mch.weixin.qq.com/pay/unifiedorder";  
    
    @SuppressWarnings("unchecked")
    public static String getPrepayId(SortedMap<String, String> params){
    	try {
			TenpayHttpClient client = new TenpayHttpClient();
			String result = "";
			if (client.callHttpPost(unifiedorder, getXml(params))){
				result = client.getResContent();
				System.out.println(result);
				Map<String, String> map = XMLUtil.doXMLParse(result);
				return map.get("prepay_id");
			}
		} catch (Exception e) {
			
		}
    	return null;
    }
    
    @SuppressWarnings("unchecked")
	public static String getCodeUrl(SortedMap<String, String> params){
    	try {
    		TenpayHttpClient client = new TenpayHttpClient();
			String result = "";
			if (client.callHttpPost(unifiedorder, getXml(params))){
				result = client.getResContent();
				System.out.println(result);
				Map<String, String> map = XMLUtil.doXMLParse(result);
				return map.get("code_url");
			}
		} catch (Exception e) {
		}
    	return null;
    }
    
    @SuppressWarnings("rawtypes")
	private static String getXml(SortedMap<String, String> params){
    	String sign = createSign(params);
    	params.put("sign", sign);
    	StringBuffer sb = new StringBuffer();
    	sb.append("<xml>");
    	Set set = params.entrySet();
    	Iterator it = set.iterator();
    	while (it.hasNext()) {
			Map.Entry object = (Map.Entry) it.next();
			String k = (String)object.getKey();
			String v = (String)object.getValue();
			if ("attach".equalsIgnoreCase(k)||"body".equalsIgnoreCase(k)||"sign".equalsIgnoreCase(k)){
				sb.append("<"+k+">"+"<![CDATA["+v+"]]></"+k+">");
			}else {
				sb.append("<"+k+">"+v+"</"+k+">");
			}
		}
    	sb.append("</xml>");
    	return sb.toString();
    }
    
    @SuppressWarnings("rawtypes")
	public static String createSign(SortedMap<String, String> params){
    	StringBuffer sb = new StringBuffer();
		Set es = params.entrySet();
		Iterator it = es.iterator();
		while(it.hasNext()) {
			Map.Entry entry = (Map.Entry)it.next();
			String k = (String)entry.getKey();
			String v = (String)entry.getValue();
			if(null != v && !"".equals(v) 
					&& !"sign".equals(k) && !"key".equals(k)) {
				sb.append(k + "=" + v + "&");
			}
		}
		sb.append("key=" + ConstantUtil.APP_KEY);
		
		String sign = MD5Util.MD5Encode(sb.toString(), "utf-8").toUpperCase();
		
		return sign;
    }
    
    public static boolean isValiSign(SortedMap<String, String> params){
    	String sign = (String)params.get("sign").toUpperCase();
    	return createSign(params).equals(sign);
    }
    
	/**
	 * 微信预支付-app-预支付id
	 */
	public static String wxPrepareId(BigDecimal price,String orderId,String info, String ip) throws Exception{
		SortedMap<String, String> params = new TreeMap<String, String>();
		params.put("body", info);
		params.put("out_trade_no", orderId);
		params.put("total_fee", price.multiply(new BigDecimal(100)).intValue()+"");
		params.put("spbill_create_ip", ip);
		return getPrepayId(wxPrepareId(params));
	}
	 
	/**
	 * 微信预支付-扫码获取url
	 */
	public static String wxCodeUrl(BigDecimal price,String orderId,String info, String ip){
		SortedMap<String, String> params = new TreeMap<String, String>();
		params.put("body", info);
		params.put("out_trade_no", orderId);
		params.put("total_fee", price.multiply(new BigDecimal(100)).intValue()+"");
		params.put("spbill_create_ip", ip);
		params.put("notify_url", ConstantUtil.BACK_URL);
		params.put("trade_type", "NATIVE"); //NATIVE JSAPI WAP  NATIVE(product_id)
		params.put("product_id", UUID.randomUUID().toString().replace("-", ""));
		params.put("device_info", "web");
		return getCodeUrl(wxPrepareId(params));
	}
	
	/**
	 * 微信预支付-扫码获取url
	 */
	public static String wxWebCodeUrl(BigDecimal price,String orderId,String info, String ip){
		SortedMap<String, String> params = new TreeMap<String, String>();
		params.put("body", info);
		params.put("out_trade_no", orderId);
		params.put("total_fee", price.multiply(new BigDecimal(100)).intValue()+"");
		params.put("spbill_create_ip", ip);
		params.put("notify_url", ConstantUtil.BACK_URL);
		params.put("trade_type", "NATIVE"); //NATIVE JSAPI WAP  NATIVE(product_id)
		params.put("product_id", UUID.randomUUID().toString().replace("-", ""));
		params.put("device_info", "web");
		return getCodeUrl(wxWebPrepareId(params));
	}
	
	/**
	 * 微信预支付-扫码获取url
	 */
	public static String wxWapCodeUrl(BigDecimal price,String orderId,String info, String ip,String openId){
		SortedMap<String, String> params = new TreeMap<String, String>();
		params.put("body", info);
		params.put("out_trade_no", orderId);
		params.put("total_fee", price.multiply(new BigDecimal(100)).intValue()+"");
		params.put("spbill_create_ip", ip);
		params.put("notify_url", ConstantUtil.BACK_URL);
		params.put("trade_type", "JSAPI"); //NATIVE JSAPI WAP  NATIVE(product_id)
		params.put("product_id", UUID.randomUUID().toString().replace("-", ""));
		params.put("device_info", "web");
		params.put("openid", openId);
		params = wxWebPrepareId(params);
		return getPrepayId(params);
	}
	/**
	 * 微信预支付-扫码获取url
	 */
	public static String wxWapRechargeCodeUrl(BigDecimal price,String orderId,String info, String ip,String openId){
		SortedMap<String, String> params = new TreeMap<String, String>();
		params.put("body", info);
		params.put("out_trade_no", orderId);
		params.put("total_fee", price.multiply(new BigDecimal(100)).intValue()+"");
		params.put("spbill_create_ip", ip);
		params.put("notify_url",  PayPropertySupport.getProperty("wx.rechargeBackUrl"));
		params.put("trade_type", "JSAPI"); //NATIVE JSAPI WAP  NATIVE(product_id)
		params.put("product_id", UUID.randomUUID().toString().replace("-", ""));
		params.put("device_info", "web");
		params.put("openid", openId);
		params = wxWebPrepareId(params);
		return getPrepayId(params);
	}
	
	public static void main(String[] args) throws Exception{
		System.out.println(wxCodeUrl(new BigDecimal(0.01), "12315326534", "测试", "8.8.8.8"));
	}
	
	/**
	 * 微信预支付
	 * @param map
	 * @return
	 */
	public static SortedMap<String, String> wxPrepareId(Map<String, String> map){
		SortedMap<String, String> params = new TreeMap<String, String>();
		params.put("appid", ConstantUtil.APP_ID);
		params.put("mch_id", ConstantUtil.PARTNER);
		params.put("nonce_str", WXUtil.getNonceStr());
		params.put("body", "微信订单");
		params.put("out_trade_no", WXUtil.getTimeStamp());
		params.put("total_fee", "0.01");
		params.put("spbill_create_ip", "8.8.8.8");
		params.put("notify_url", ConstantUtil.BACK_URL);
		params.put("trade_type", "APP");
		params.putAll(map);
		return params;
	}
	
	/**
	 * 微信预支付
	 * @param map
	 * @return
	 */
	public static SortedMap<String, String> wxWebPrepareId(Map<String, String> map){
		SortedMap<String, String> params = new TreeMap<String, String>();
		params.put("appid", ConstantUtil.WEB_APP_ID);
		params.put("mch_id", ConstantUtil.WEB_PARTNER);
		params.put("nonce_str", WXUtil.getNonceStr());
		params.put("body", "微信订单");
		params.put("out_trade_no", WXUtil.getTimeStamp());
		params.put("total_fee", "0.01");
		params.put("spbill_create_ip", "8.8.8.8");
		params.put("notify_url", ConstantUtil.BACK_URL);
		params.put("trade_type", "WAP");
		params.putAll(map);
		return params;
	}
}
